{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ABU量化系统使用文档 \n",
    "\n",
    "<center>\n",
    "        <img src=\"./image/abu_logo.png\" alt=\"\" style=\"vertical-align:middle;padding:10px 20px;\"><font size=\"6\" color=\"black\"><b>第26节 星期几是这个股票的‘好日子’</b></font>\n",
    "</center>\n",
    "\n",
    "-----------------\n",
    "\n",
    "\n",
    "作者: 阿布\n",
    "\n",
    "阿布量化版权所有 未经允许 禁止转载\n",
    "\n",
    "[abu量化系统github地址](https://github.com/bbfamily/abu) (欢迎+star)\n",
    "\n",
    "[本节ipython notebook](https://github.com/bbfamily/abu/tree/master/abupy_lecture)\n",
    "\n",
    "[本节界面操作教程视频](https://v.qq.com/x/page/l0556oqgemk.html)\n",
    "\n",
    "\n",
    "上一节讲解量化交易中跨市场低频统计套利的示例，本节将示例一个与周期相关的短线择时策略，本节的内容是为《量化交易之路》中的一个小节做的完整策略实例补充。\n",
    "\n",
    "首先导入本节需要使用的abupy中的模块： "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "enable example env will only read RomDataBu/df_kl.h5\n"
     ]
    }
   ],
   "source": [
    "# 基础库导入\n",
    "\n",
    "from __future__ import print_function\n",
    "from __future__ import division\n",
    "\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "warnings.simplefilter('ignore')\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "import os\n",
    "import sys\n",
    "# 使用insert 0即只使用github，避免交叉使用了pip安装的abupy，导致的版本不一致问题\n",
    "sys.path.insert(0, os.path.abspath('../'))\n",
    "import abupy\n",
    "\n",
    "# 使用沙盒数据，目的是和书中一样的数据环境\n",
    "abupy.env.enable_example_env_ipython()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from abupy import abu, AbuFactorBuyTD, BuyCallMixin, ABuSymbolPd, ABuKLUtil\n",
    "from abupy import AbuFactorSellNDay, AbuMetricsBase, ABuProgress"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "很多刚接触交易的人总喜欢把交易看成一种有固定收入的工作，比如他们有自己的规矩，周五一定要把所有股票都卖了，安安心心过周末，周一看情况一切良好再把股票买回来。\n",
    "\n",
    "还有一些人有着很奇怪的癖好认为周三是他的幸运日，在周三买入他选中的股票，有些人每个月第一个周五发工资，市场就是由这些各种各样的人组成的。\n",
    "\n",
    "某一个股票上的活跃用户在一段短时间内变化并不大，也就是说这些习惯周五卖周一买的人会反复在一支股票上交易，普通投资者普遍的投资方式是针对一支股票不断的进行买卖，他们不会长期持有这支股票，但也不会远离这支股票很长时间，我认为有两点促成了以上事实。\n",
    "\n",
    "1. 贪欲：贪欲在这中间起到了很大的作用，当一个人第一次买入一支股票并且持有到有一定利润的时候，他选择卖出这支股票，因为他认为涨的已经很多了，该适当的回调了，之后股价的走势只有两种可能：第一按照他的预期下跌，这样的话他可能选择跌到某种程度再次进场买入这支股票；第二就是继续上涨，这种情况下他会选择不断‘诅咒’这支股票，直到有一天股价上涨到让他无法忍受，从此由‘黑转粉’。 \n",
    "\n",
    "2. 时间成本与懒惰：一个人类的时间和精力都是有限的，它无法获取市场中所有股票的信息，每次获取熟悉一支股票的时间成本在他看来也是非常巨大，他反复的盯着自己最频繁买卖的那几支股票。\n",
    "\n",
    "\n",
    "### 1. 美股周期短线分析\n",
    "\n",
    "下面先获取沙盒数据中美股一年的数据，做为短线分析示例："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "us_choice_symbols = ['usTSLA', 'usNOAH', 'usSFUN', 'usBIDU', 'usAAPL', 'usGOOG', 'usWUBA', 'usVIPS']\n",
    "kl_dict = {us_symbol[2:]: \n",
    " ABuSymbolPd.make_kl_df(us_symbol, start='2014-07-26', end='2015-07-26') \n",
    " for us_symbol in us_choice_symbols}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从日振幅涨跌幅比来看，只有BIDU和WUBA能勉强有短线套利的空间（值 > 1.8）, 但是由于沙盒数据中只有这些symbol，所以暂时忽略这个特证，之后做非沙盒数据全市场周期短线分析时再使用这个值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "TSLA日振幅涨跌幅比：1.778420\n",
      "NOAH日振幅涨跌幅比：1.733710\n",
      "SFUN日振幅涨跌幅比：1.784097\n",
      "BIDU日振幅涨跌幅比：1.812175\n",
      "AAPL日振幅涨跌幅比：1.664462\n",
      "GOOG日振幅涨跌幅比：1.573070\n",
      "WUBA日振幅涨跌幅比：1.913431\n",
      "VIPS日振幅涨跌幅比：1.568457\n"
     ]
    }
   ],
   "source": [
    "ABuKLUtil.wave_change_rate(kl_dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下面先一个一个观察每一个股票的周期涨跌概率，可以发现：\n",
    "\n",
    "1. 特斯拉在周四上涨的概率最大59%\n",
    "2. 诺亚财富也在周四上涨的概率最大65%\n",
    "3. 百度在周五上涨概率达到60%\n",
    "4. 苹果在周三上涨概率达到56%"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>TSLAwin</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>NOAHwin</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>SFUNwin</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>BIDUwin</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>AAPLwin</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>GOOGwin</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>WUBAwin</th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>VIPSwin</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date_week</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>周一</th>\n",
       "      <td>24</td>\n",
       "      <td>23</td>\n",
       "      <td>0.49</td>\n",
       "      <td>24</td>\n",
       "      <td>23</td>\n",
       "      <td>0.49</td>\n",
       "      <td>29</td>\n",
       "      <td>18</td>\n",
       "      <td>0.38</td>\n",
       "      <td>27</td>\n",
       "      <td>21</td>\n",
       "      <td>0.44</td>\n",
       "      <td>22</td>\n",
       "      <td>26</td>\n",
       "      <td>0.54</td>\n",
       "      <td>27</td>\n",
       "      <td>20</td>\n",
       "      <td>0.43</td>\n",
       "      <td>23</td>\n",
       "      <td>24</td>\n",
       "      <td>0.51</td>\n",
       "      <td>26</td>\n",
       "      <td>21</td>\n",
       "      <td>0.45</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>周二</th>\n",
       "      <td>26</td>\n",
       "      <td>26</td>\n",
       "      <td>0.50</td>\n",
       "      <td>25</td>\n",
       "      <td>27</td>\n",
       "      <td>0.52</td>\n",
       "      <td>29</td>\n",
       "      <td>23</td>\n",
       "      <td>0.44</td>\n",
       "      <td>33</td>\n",
       "      <td>19</td>\n",
       "      <td>0.37</td>\n",
       "      <td>33</td>\n",
       "      <td>19</td>\n",
       "      <td>0.37</td>\n",
       "      <td>27</td>\n",
       "      <td>25</td>\n",
       "      <td>0.48</td>\n",
       "      <td>30</td>\n",
       "      <td>22</td>\n",
       "      <td>0.42</td>\n",
       "      <td>29</td>\n",
       "      <td>23</td>\n",
       "      <td>0.44</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>周三</th>\n",
       "      <td>26</td>\n",
       "      <td>26</td>\n",
       "      <td>0.50</td>\n",
       "      <td>27</td>\n",
       "      <td>25</td>\n",
       "      <td>0.48</td>\n",
       "      <td>30</td>\n",
       "      <td>22</td>\n",
       "      <td>0.42</td>\n",
       "      <td>29</td>\n",
       "      <td>23</td>\n",
       "      <td>0.44</td>\n",
       "      <td>23</td>\n",
       "      <td>29</td>\n",
       "      <td>0.56</td>\n",
       "      <td>26</td>\n",
       "      <td>26</td>\n",
       "      <td>0.50</td>\n",
       "      <td>28</td>\n",
       "      <td>24</td>\n",
       "      <td>0.46</td>\n",
       "      <td>24</td>\n",
       "      <td>28</td>\n",
       "      <td>0.54</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>周四</th>\n",
       "      <td>20</td>\n",
       "      <td>29</td>\n",
       "      <td>0.59</td>\n",
       "      <td>17</td>\n",
       "      <td>32</td>\n",
       "      <td>0.65</td>\n",
       "      <td>25</td>\n",
       "      <td>24</td>\n",
       "      <td>0.49</td>\n",
       "      <td>25</td>\n",
       "      <td>24</td>\n",
       "      <td>0.49</td>\n",
       "      <td>22</td>\n",
       "      <td>27</td>\n",
       "      <td>0.55</td>\n",
       "      <td>22</td>\n",
       "      <td>27</td>\n",
       "      <td>0.55</td>\n",
       "      <td>29</td>\n",
       "      <td>20</td>\n",
       "      <td>0.41</td>\n",
       "      <td>28</td>\n",
       "      <td>21</td>\n",
       "      <td>0.43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>周五</th>\n",
       "      <td>28</td>\n",
       "      <td>22</td>\n",
       "      <td>0.44</td>\n",
       "      <td>24</td>\n",
       "      <td>26</td>\n",
       "      <td>0.52</td>\n",
       "      <td>28</td>\n",
       "      <td>22</td>\n",
       "      <td>0.44</td>\n",
       "      <td>20</td>\n",
       "      <td>30</td>\n",
       "      <td>0.60</td>\n",
       "      <td>24</td>\n",
       "      <td>26</td>\n",
       "      <td>0.52</td>\n",
       "      <td>27</td>\n",
       "      <td>23</td>\n",
       "      <td>0.46</td>\n",
       "      <td>23</td>\n",
       "      <td>27</td>\n",
       "      <td>0.54</td>\n",
       "      <td>23</td>\n",
       "      <td>27</td>\n",
       "      <td>0.54</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            0   1  TSLAwin   0   1  NOAHwin   0   1  SFUNwin   0   1  BIDUwin  \\\n",
       "date_week                                                                       \n",
       "周一         24  23     0.49  24  23     0.49  29  18     0.38  27  21     0.44   \n",
       "周二         26  26     0.50  25  27     0.52  29  23     0.44  33  19     0.37   \n",
       "周三         26  26     0.50  27  25     0.48  30  22     0.42  29  23     0.44   \n",
       "周四         20  29     0.59  17  32     0.65  25  24     0.49  25  24     0.49   \n",
       "周五         28  22     0.44  24  26     0.52  28  22     0.44  20  30     0.60   \n",
       "\n",
       "            0   1  AAPLwin   0   1  GOOGwin   0   1  WUBAwin   0   1  VIPSwin  \n",
       "date_week                                                                      \n",
       "周一         22  26     0.54  27  20     0.43  23  24     0.51  26  21     0.45  \n",
       "周二         33  19     0.37  27  25     0.48  30  22     0.42  29  23     0.44  \n",
       "周三         23  29     0.56  26  26     0.50  28  24     0.46  24  28     0.54  \n",
       "周四         22  27     0.55  22  27     0.55  29  20     0.41  28  21     0.43  \n",
       "周五         24  26     0.52  27  23     0.46  23  27     0.54  23  27     0.54  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.options.display.precision = 2\n",
    "pd.options.display.max_columns = 30\n",
    "ABuKLUtil.date_week_win(kl_dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "假如择时策略中需要找到每一个股票上涨概率超过55%的交易日，做为策略买入的日子，比如下面示例找特斯拉超过55%的交易日："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>win</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date_week</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>周四</th>\n",
       "      <td>20</td>\n",
       "      <td>29</td>\n",
       "      <td>0.59</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            0   1   win\n",
       "date_week              \n",
       "周四         20  29  0.59"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tl_dw = ABuKLUtil.date_week_win(kl_dict['TSLA'])\n",
    "tl_dw_vd = tl_dw[tl_dw.win > 0.55]\n",
    "tl_dw_vd"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到上面的结果就是符号要求的交易日，但是如果虽然周四的胜率很很高，但是周四的上涨比例很低呢，如果上涨比例很低，会造成盈亏比很低，造成最终交易依然亏损，下面使用date_week_mean看看上面各个美股每个交易日的涨跌比例，如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>TSLA_p_change</th>\n",
       "      <th>NOAH_p_change</th>\n",
       "      <th>SFUN_p_change</th>\n",
       "      <th>BIDU_p_change</th>\n",
       "      <th>AAPL_p_change</th>\n",
       "      <th>GOOG_p_change</th>\n",
       "      <th>WUBA_p_change</th>\n",
       "      <th>VIPS_p_change</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date_week</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>周一</th>\n",
       "      <td>-0.11</td>\n",
       "      <td>-0.04</td>\n",
       "      <td>-0.79</td>\n",
       "      <td>-0.32</td>\n",
       "      <td>0.26</td>\n",
       "      <td>-0.16</td>\n",
       "      <td>0.15</td>\n",
       "      <td>-0.33</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>周二</th>\n",
       "      <td>0.39</td>\n",
       "      <td>0.16</td>\n",
       "      <td>-0.25</td>\n",
       "      <td>-0.11</td>\n",
       "      <td>-0.14</td>\n",
       "      <td>-0.17</td>\n",
       "      <td>0.64</td>\n",
       "      <td>-1.52</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>周三</th>\n",
       "      <td>-0.19</td>\n",
       "      <td>-0.29</td>\n",
       "      <td>-0.46</td>\n",
       "      <td>-0.06</td>\n",
       "      <td>0.11</td>\n",
       "      <td>0.03</td>\n",
       "      <td>-0.28</td>\n",
       "      <td>0.15</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>周四</th>\n",
       "      <td>0.54</td>\n",
       "      <td>1.26</td>\n",
       "      <td>0.48</td>\n",
       "      <td>0.13</td>\n",
       "      <td>0.20</td>\n",
       "      <td>0.17</td>\n",
       "      <td>-0.13</td>\n",
       "      <td>-0.17</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>周五</th>\n",
       "      <td>-0.19</td>\n",
       "      <td>0.07</td>\n",
       "      <td>0.29</td>\n",
       "      <td>0.25</td>\n",
       "      <td>0.11</td>\n",
       "      <td>0.25</td>\n",
       "      <td>0.42</td>\n",
       "      <td>0.13</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           TSLA_p_change  NOAH_p_change  SFUN_p_change  BIDU_p_change  \\\n",
       "date_week                                                               \n",
       "周一                 -0.11          -0.04          -0.79          -0.32   \n",
       "周二                  0.39           0.16          -0.25          -0.11   \n",
       "周三                 -0.19          -0.29          -0.46          -0.06   \n",
       "周四                  0.54           1.26           0.48           0.13   \n",
       "周五                 -0.19           0.07           0.29           0.25   \n",
       "\n",
       "           AAPL_p_change  GOOG_p_change  WUBA_p_change  VIPS_p_change  \n",
       "date_week                                                              \n",
       "周一                  0.26          -0.16           0.15          -0.33  \n",
       "周二                 -0.14          -0.17           0.64          -1.52  \n",
       "周三                  0.11           0.03          -0.28           0.15  \n",
       "周四                  0.20           0.17          -0.13          -0.17  \n",
       "周五                  0.11           0.25           0.42           0.13  "
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ABuKLUtil.date_week_mean(kl_dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "看看特斯拉满足胜率要求的交易日中的涨跌幅比例，如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>_p_change</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date_week</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>周四</th>\n",
       "      <td>0.54</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           _p_change\n",
       "date_week           \n",
       "周四              0.54"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tl_dwm = ABuKLUtil.date_week_mean(kl_dict['TSLA'])\n",
    "tl_dwm.loc[tl_dw_vd.index]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到周四的涨跌平均值是0.54，在具体策略编写中可以使用如下两种阀值计算方式，确定周四的涨幅比例是否高于下面两种算法："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0.73209375244226405, 0.45709539602153293)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "abs(tl_dwm.sum()).values[0] / 0.618, abs(tl_dwm._p_change).mean() / 0.618"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到第一种算法的值计算为0.73，第二种为0.45，0.54虽然大于0.45但是小于0.73，即虽然特斯拉在周四有大概率的上涨可能，如果使用第一种算法，那么由于涨幅比例不符合要求，在具体策略中将不会发出买入信号。\n",
    "\n",
    "备注：\n",
    "\n",
    "1. 上面的计算中0.618是可以在具体策略中通过参数传递\n",
    "2. 无论是上面使用的55%胜率还是0.618都是以制造非均衡概率优势为目的\n",
    "3. 在实际策略编写中根据交易量需求，以及市场交易目标数量等等确定具体使用上面那一种算法, 或两个并行生效"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下面看看百度上涨概率超过55%的交易日："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>win</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date_week</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>周五</th>\n",
       "      <td>20</td>\n",
       "      <td>30</td>\n",
       "      <td>0.6</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            0   1  win\n",
       "date_week             \n",
       "周五         20  30  0.6"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bd_dw = ABuKLUtil.date_week_win(kl_dict['BIDU'])\n",
    "bd_dw_vd = bd_dw[bd_dw.win > 0.55]\n",
    "bd_dw_vd"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "看看百度满足胜率要求的交易日中的涨跌幅比例，以及两种阀值计算，如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.171504714657 0.2820732168894443\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>_p_change</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date_week</th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>周五</th>\n",
       "      <td>0.25</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           _p_change\n",
       "date_week           \n",
       "周五              0.25"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bd_dwm = ABuKLUtil.date_week_mean(kl_dict['BIDU'])\n",
    "print(abs(bd_dwm.sum()).values[0] / 0.618, abs(bd_dwm._p_change).mean() / 0.618)\n",
    "bd_dwm.loc[bd_dw_vd.index]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "结果看到第一种算法的值计算为0.17，第二种为0.28，0.25虽然大于0.17但是小于0.28，即如果策略中使用第一种阀值计算方式将满足买入信号发出，如果第二种就不满足。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. 日胜率均值回复策略\n",
    "\n",
    "实盘中使用的symbol数量会远远多于本例中使用沙盒数据的数量，策略可以要求两种阀值都满足，且加入更多的非均衡条件构造最终的非均衡结果，但是由于本例沙盒数据量少，所以下面编写策略时采用两种阀值计算方式满足一种即可，策略大概原理如下：\n",
    "\n",
    "策略的性质属于：**均值回复**\n",
    "\n",
    "1. 默认以40天为周期(8周)结合涨跌阀值计算周几适合买入\n",
    "2. 回测运行中每一个月重新计算一次上述的周几适合买入\n",
    "3. 在策略日任务中买入信号为：昨天下跌，今天开盘也下跌，且明天是计算出来的上涨概率大的'周几'\n",
    "\n",
    "具体策略编写如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class AbuFactorBuyWD(AbuFactorBuyTD, BuyCallMixin):\n",
    "    def _init_self(self, **kwargs):\n",
    "        \"\"\"\n",
    "            kwargs中可选参数：buy_dw:    代表周期胜率阀值，默认0.55即55%\n",
    "            kwargs中可选参数：buy_dwm:   代表涨幅比例阀值系数，默认0.618\n",
    "            kwargs中可选参数：dw_period: 代表分析dw，dwm所使用的交易周期，默认40天周期(8周)\n",
    "        \"\"\"\n",
    "        self.buy_dw    = kwargs.pop('buy_dw', 0.55)\n",
    "        self.buy_dwm   = kwargs.pop('buy_dwm', 0.618)\n",
    "        self.dw_period = kwargs.pop('dw_period', 40)\n",
    "        \n",
    "        # combine_kl_pd中包含择时金融时间数据与择时之前一年的金融时间数据, 先取出择时开始之前的周期数据\n",
    "        last_kl = self.combine_kl_pd.loc[:self.kl_pd.index[0]]\n",
    "        if last_kl.shape[0] > self.dw_period:\n",
    "            last_kl = last_kl[-self.dw_period:]\n",
    "        # 开始计算周几买，_make_buy_date把结果被放在self.buy_date_week序列中\n",
    "        self._make_buy_date(last_kl)\n",
    "\n",
    "    def fit_month(self, today):\n",
    "        \"\"\"月任务，每一个重新取之前一年的金融时间序列数据，重新计算一遍'周几买'\"\"\"\n",
    "        end_ind = self.combine_kl_pd[self.combine_kl_pd.date == today.date].key.values[0]\n",
    "        start_ind = end_ind - self.dw_period  if end_ind - self.dw_period  > 0 else 0\n",
    "        # 根据当前的交易日，切片过去的一年金融时间序列\n",
    "        last_kl = self.combine_kl_pd.iloc[start_ind:end_ind]\n",
    "        # 重新计算一遍'周几买'\n",
    "        self._make_buy_date(last_kl)\n",
    "\n",
    "    def fit_day(self, today):\n",
    "        \"\"\"日任务：昨天下跌，今天开盘也下跌，根据今天是周几，在不在序列self.buy_date_week中决定今天买不买\"\"\"\n",
    "        if self.yesterday.p_change < 0 and today.open < self.yesterday.close \\\n",
    "            and int(today.date_week) in self.buy_date_week:\n",
    "            # 由于没有用到今天的收盘价格等，可以直接使用buy_today\n",
    "            return self.buy_today()\n",
    "        return None\n",
    "\n",
    "    # noinspection PyProtectedMember\n",
    "    def _make_buy_date(self, last_kl):\n",
    "        self.buy_date_week = []\n",
    "        # 计算周期内，周期的胜率\n",
    "        last_dw = ABuKLUtil.date_week_win(last_kl)\n",
    "        # 摘取大于阀值self.buy_dw的'周几'，buy_dw默认0.55\n",
    "        last_dw_vd = last_dw[last_dw.win >= self.buy_dw]\n",
    "        \"\"\"\n",
    "            eg: last_dw_vd\n",
    "                       0  1   win\n",
    "            date_week            \n",
    "            周四         3  5  0.62\n",
    "            周五         2  6  0.75\n",
    "        \"\"\"\n",
    "        if len(last_dw_vd) > 0:\n",
    "            # 如果胜率有符合要求的，使用周几平均涨幅计算date_week_mean\n",
    "            last_dwm = ABuKLUtil.date_week_mean(last_kl)\n",
    "            # 摘取满足胜率的last_dw_vd\n",
    "            last_dwm_vd = last_dwm.loc[last_dw_vd.index]\n",
    "            \"\"\"\n",
    "                eg: last_dwm_vd\n",
    "                           _p_change\n",
    "                date_week           \n",
    "                周四              1.55\n",
    "                周五              1.12\n",
    "            \"\"\"\n",
    "            # 阀值计算方式1\n",
    "            dwm1 = abs(last_dwm.sum()).values[0] / self.buy_dwm\n",
    "            # 阀值计算方式2\n",
    "            dwm2 = abs(last_dwm._p_change).mean() / self.buy_dwm\n",
    "            # 如果symbol多可以使用&的关系\n",
    "            dm_effect = (last_dwm_vd._p_change > dwm1) | (last_dwm_vd._p_change > dwm2)\n",
    "            buy_date_loc = last_dwm_vd[dm_effect].index\n",
    "            \"\"\"\n",
    "                eg: buy_date_loc\n",
    "                Index(['周四', '周五'], dtype='object', name='date_week')\n",
    "            \"\"\"\n",
    "            if len(buy_date_loc) > 0:\n",
    "                # 如果涨跌幅阀值也满足，tolist，eg：['周一', '周二', '周三', '周四', '周五']\n",
    "                dw_index = last_dw.index.tolist()\n",
    "                # 如果是一周5个交易日的就是4，如果是比特币等7天交易日的就是6\n",
    "                max_ind = len(dw_index) - 1\n",
    "                for bdl in buy_date_loc:\n",
    "                    sell_ind = dw_index.index(bdl)\n",
    "                    buy_ind = sell_ind - 1 if sell_ind > 0 else max_ind\n",
    "                    self.buy_date_week.append(buy_ind)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. 各个市场回测日胜率均值回复策略\n",
    "\n",
    "上面的AbuFactorBuyWD即完成了整个策略的编写，下面开始进行回测，如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入后卖出的交易数量:146\n",
      "买入后尚未卖出的交易数量:2\n",
      "胜率:53.4247%\n",
      "平均获利期望:1.9614%\n",
      "平均亏损期望:-1.9299%\n",
      "盈亏比:1.1534\n",
      "所有交易收益比例和:0.2369 \n",
      "所有交易总盈亏和:24655.9100 \n"
     ]
    }
   ],
   "source": [
    "# 初始化资金\n",
    "read_cash = 1000000\n",
    "# 买入策略AbuFactorBuyWD，参数都使用默认的\n",
    "buy_factors = [{'class': AbuFactorBuyWD}]\n",
    "# 卖出策略使用AbuFactorSellNDay，sell_n=1即只持有一天，is_sell_today=True, 持有一天后当天卖出\n",
    "sell_factors = [{'class': AbuFactorSellNDay, 'sell_n': 1, 'is_sell_today': True}]\n",
    "\n",
    "def run_loo_back(choice_symbols, start, end):\n",
    "    abu_result_tuple, _ = abu.run_loop_back(read_cash,\n",
    "                                           buy_factors,\n",
    "                                           sell_factors,\n",
    "                                           start=start,\n",
    "                                           end=end,\n",
    "                                           choice_symbols=choice_symbols, n_process_pick=1)\n",
    "    ABuProgress.clear_output()\n",
    "    AbuMetricsBase.show_general(*abu_result_tuple, returns_cmp=True, only_info=True)\n",
    "    return abu_result_tuple\n",
    "# 开始进行美股沙盒数据回测，沙盒数据中美股只有从13年7月到16年7月的数据，其它市场会多一些\n",
    "abu_result_tuple = run_loo_back(us_choice_symbols, '2013-07-26', '2016-07-26')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到上面的回测中胜率超过了50%，从下面的交易单中可以看到所有交易都只持有了一天，如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>symbol</th>\n",
       "      <th>buy_date</th>\n",
       "      <th>sell_date</th>\n",
       "      <th>keep_days</th>\n",
       "      <th>profit</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2013-08-13</th>\n",
       "      <td>usVIPS</td>\n",
       "      <td>20130813</td>\n",
       "      <td>20130814</td>\n",
       "      <td>1</td>\n",
       "      <td>-2893.36</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-09-30</th>\n",
       "      <td>usBIDU</td>\n",
       "      <td>20130930</td>\n",
       "      <td>20131001</td>\n",
       "      <td>1</td>\n",
       "      <td>5626.25</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-10-02</th>\n",
       "      <td>usTSLA</td>\n",
       "      <td>20131002</td>\n",
       "      <td>20131003</td>\n",
       "      <td>1</td>\n",
       "      <td>-7767.15</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-10-15</th>\n",
       "      <td>usBIDU</td>\n",
       "      <td>20131015</td>\n",
       "      <td>20131016</td>\n",
       "      <td>1</td>\n",
       "      <td>193.80</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-10-23</th>\n",
       "      <td>usTSLA</td>\n",
       "      <td>20131023</td>\n",
       "      <td>20131024</td>\n",
       "      <td>1</td>\n",
       "      <td>1808.34</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-10-28</th>\n",
       "      <td>usBIDU</td>\n",
       "      <td>20131028</td>\n",
       "      <td>20131029</td>\n",
       "      <td>1</td>\n",
       "      <td>522.06</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2013-10-31</th>\n",
       "      <td>usTSLA</td>\n",
       "      <td>20131031</td>\n",
       "      <td>20131101</td>\n",
       "      <td>1</td>\n",
       "      <td>3408.82</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            symbol  buy_date  sell_date  keep_days   profit\n",
       "2013-08-13  usVIPS  20130813   20130814          1 -2893.36\n",
       "2013-09-30  usBIDU  20130930   20131001          1  5626.25\n",
       "2013-10-02  usTSLA  20131002   20131003          1 -7767.15\n",
       "2013-10-15  usBIDU  20131015   20131016          1   193.80\n",
       "2013-10-23  usTSLA  20131023   20131024          1  1808.34\n",
       "2013-10-28  usBIDU  20131028   20131029          1   522.06\n",
       "2013-10-31  usTSLA  20131031   20131101          1  3408.82"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "abu_result_tuple.orders_pd.filter(\n",
    "    ['symbol', 'buy_date', 'sell_date', 'keep_days', 'profit'])[:7]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上面的策略中计算'周几'上涨概率最大的交易周期默认为40天周期(8周)，这个周期长度不能太长也不能太短，因为某一个股票上的活跃用户只是在一段短时间内变化不大，但是一个市场中的参与者随着时间的流逝，也在慢慢不断变化，不断新老交替，就像我们人类，每7年我们就是一个全新的自己，所有细胞血液都将完全更新一遍。\n",
    "\n",
    "下面使用这个策略对比特币，莱特币进行回测，如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入后卖出的交易数量:24\n",
      "买入后尚未卖出的交易数量:0\n",
      "胜率:58.3333%\n",
      "平均获利期望:2.8335%\n",
      "平均亏损期望:-2.6652%\n",
      "盈亏比:1.8846\n",
      "所有交易收益比例和:0.1302 \n",
      "所有交易总盈亏和:18321.1800 \n"
     ]
    }
   ],
   "source": [
    "_ = run_loo_back(['btc', 'ltc'], '2013-07-26', '2017-07-26')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下面使用这个沙盒中A股市场symbol进行回测，如下所示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "买入后卖出的交易数量:112\n",
      "买入后尚未卖出的交易数量:1\n",
      "胜率:55.3571%\n",
      "平均获利期望:1.8545%\n",
      "平均亏损期望:-2.0521%\n",
      "盈亏比:1.0527\n",
      "所有交易收益比例和:0.1237 \n",
      "所有交易总盈亏和:6612.0000 \n"
     ]
    }
   ],
   "source": [
    "cn_choice_symbols = ['002230', '300104', '300059', '601766', '600085', '600036', '600809', '000002', '002594']\n",
    "_ = run_loo_back(cn_choice_symbols, '2013-07-26', '2017-07-26')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "小结：\n",
    "\n",
    "上面的回测交易由于使用沙盒数据，数据量少，所以实际上的回测效果一般，即如果一个策略有56%的胜率，那么一天只执行10次交易，你的胜率有各种可能，不一定达到56%，但是如果你能一天执行10000次以上，那么你的胜率如果不是56%，不管是更多或者更少，都代表你计算胜率的方式有问题。\n",
    "\n",
    "所以针对上面这个策略，确定你拥有交易概率优势，只要一天内可以从不同市场、不同股票、不同时段内找到足够多的交易机会，执行足够多的次数，那你最后一定是盈利的，统计套利的核心思想就是这个，不只是要单纯追求胜率，更应该关注大数定律，寻找多元化的交易机会，最终达成理想的胜率。\n",
    "\n",
    "在之后的章节中会示例不使用沙盒数据，在各个市场中通过这个策略寻找交易进行进行回测，请关注公众号中的代码示例更新"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "#### abu量化文档目录章节\n",
    "\n",
    "1. [择时策略的开发](http://www.abuquant.com/lecture/lecture_1.html)\n",
    "2. [择时策略的优化](http://www.abuquant.com/lecture/lecture_2.html)\n",
    "3. [滑点策略与交易手续费](http://www.abuquant.com/lecture/lecture_3.html)\n",
    "4. [多支股票择时回测与仓位管理](http://www.abuquant.com/lecture/lecture_4.html)\n",
    "5. [选股策略的开发](http://www.abuquant.com/lecture/lecture_5.html)\n",
    "6. [回测结果的度量](http://www.abuquant.com/lecture/lecture_6.html)\n",
    "7. [寻找策略最优参数和评分](http://www.abuquant.com/lecture/lecture_7.html)\n",
    "8. [A股市场的回测](http://www.abuquant.com/lecture/lecture_8.html)\n",
    "9. [港股市场的回测](http://www.abuquant.com/lecture/lecture_9.html)\n",
    "10. [比特币，莱特币的回测](http://www.abuquant.com/lecture/lecture_10.html)\n",
    "11. [期货市场的回测](http://www.abuquant.com/lecture/lecture_11.html)\n",
    "12. [机器学习与比特币示例](http://www.abuquant.com/lecture/lecture_12.html)\n",
    "13. [量化技术分析应用](http://www.abuquant.com/lecture/lecture_13.html)\n",
    "14. [量化相关性分析应用](http://www.abuquant.com/lecture/lecture_14.html)\n",
    "15. [量化交易和搜索引擎](http://www.abuquant.com/lecture/lecture_15.html)\n",
    "16. [UMP主裁交易决策](http://www.abuquant.com/lecture/lecture_16.html)\n",
    "17. [UMP边裁交易决策](http://www.abuquant.com/lecture/lecture_17.html)\n",
    "18. [自定义裁判决策交易](http://www.abuquant.com/lecture/lecture_18.html)\n",
    "19. [数据源](http://www.abuquant.com/lecture/lecture_19.html)\n",
    "20. [A股全市场回测](http://www.abuquant.com/lecture/lecture_20.html)\n",
    "21. [A股UMP决策](http://www.abuquant.com/lecture/lecture_21.html)\n",
    "22. [美股全市场回测](http://www.abuquant.com/lecture/lecture_22.html)\n",
    "23. [美股UMP决策](http://www.abuquant.com/lecture/lecture_23.html)\n",
    "\n",
    "abu量化系统文档教程持续更新中，请关注公众号中的更新提醒。\n",
    "\n",
    "#### 《量化交易之路》目录章节及随书代码地址\n",
    "\n",
    "1. [第二章 量化语言——Python](https://github.com/bbfamily/abu/tree/master/ipython/第二章-量化语言——Python.ipynb)\n",
    "2. [第三章 量化工具——NumPy](https://github.com/bbfamily/abu/tree/master/ipython/第三章-量化工具——NumPy.ipynb)\n",
    "3. [第四章 量化工具——pandas](https://github.com/bbfamily/abu/tree/master/ipython/第四章-量化工具——pandas.ipynb)\n",
    "4. [第五章 量化工具——可视化](https://github.com/bbfamily/abu/tree/master/ipython/第五章-量化工具——可视化.ipynb)\n",
    "5. [第六章 量化工具——数学：你一生的追求到底能带来多少幸福](https://github.com/bbfamily/abu/tree/master/ipython/第六章-量化工具——数学.ipynb)\n",
    "6. [第七章 量化系统——入门：三只小猪股票投资的故事](https://github.com/bbfamily/abu/tree/master/ipython/第七章-量化系统——入门.ipynb)\n",
    "7. [第八章 量化系统——开发](https://github.com/bbfamily/abu/tree/master/ipython/第八章-量化系统——开发.ipynb)\n",
    "8. [第九章 量化系统——度量与优化](https://github.com/bbfamily/abu/tree/master/ipython/第九章-量化系统——度量与优化.ipynb)\n",
    "9. [第十章 量化系统——机器学习•猪老三](https://github.com/bbfamily/abu/tree/master/ipython/第十章-量化系统——机器学习•猪老三.ipynb)\n",
    "10. [第十一章 量化系统——机器学习•ABU](https://github.com/bbfamily/abu/tree/master/ipython/第十一章-量化系统——机器学习•ABU.ipynb)\n",
    "11. [附录A 量化环境部署](https://github.com/bbfamily/abu/tree/master/ipython/附录A-量化环境部署.ipynb)\n",
    "12. [附录B 量化相关性分析](https://github.com/bbfamily/abu/tree/master/ipython/附录B-量化相关性分析.ipynb)\n",
    "13. [附录C 量化统计分析及指标应用](https://github.com/bbfamily/abu/tree/master/ipython/附录C-量化统计分析及指标应用.ipynb)\n",
    "\n",
    "[更多阿布量化量化技术文章](http://www.abuquant.com/article)\n",
    "\n",
    "\n",
    "更多关于量化交易相关请阅读[《量化交易之路》](http://www.abuquant.com/books/quantify-trading-road.html)\n",
    "\n",
    "更多关于量化交易与机器学习相关请阅读[《机器学习之路》](http://www.abuquant.com/books/machine-learning-road.html)\n",
    "\n",
    "更多关于abu量化系统请关注微信公众号: abu_quant\n",
    "\n",
    "![](./image/qrcode.jpg)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
